﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Tsanie.OsuDevice.Components {
    enum WindowsArrow {
        WIN_ARROW_UP = 1024,
        WIN_ARROW_DOWN = 512
    }
    enum HorizontalImageAlignment {
        Left = 0,
        Right = 4096
    }
    [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
    struct LVCOLUMN {
        public int mask;
        public int fmt;
        public int cx;
        public IntPtr pszText;
        public int cchTextMax;
        public int iSubItem;
        public int iImage;
        public int iOrder;
    }
    class ListViewImage {
        public const int LVM_GETHEADER = 4127;
        public const int HDM_SETIMAGELIST = 4616;
        public const int LVM_SETCOLUMN = 4122;
        public const int LVCF_FMT = 1;
        public const int LVCF_IMAGE = 16;
        [DllImport("User32.dll")]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        [DllImport("User32", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVCOLUMN lParam);

        // When using the Windows Arrows there is no need to add imagelist to the header control.
        // So we can Use "NOTHING" at the place of imagelist when calling the sub
        public static void SetColumnHeaderImage(ListView listView, int column,
            HorizontalImageAlignment imageAlignment,
            WindowsArrow winArrow
        ) {
            // When using the Windows Arrows there is no need to add imagelist to the header control.
            LVCOLUMN col;
            col.mask = LVCF_FMT | LVCF_IMAGE;
            col.fmt = (int)winArrow + (int)imageAlignment;
            col.iImage = -1;
            col.cchTextMax = 0;
            col.cx = 0;
            col.iOrder = 0;
            col.iSubItem = 0;
            col.pszText = IntPtr.Zero;
            SendMessage(listView.Handle, (int)LVM_SETCOLUMN, column, ref col);
        }

        public static void SetColumnHeaderImageList(ListView listView, int column, System.Windows.Forms.ImageList imageList) {
            IntPtr hwnd = SendMessage(listView.Handle, LVM_GETHEADER, 0, 0);
            SendMessage(hwnd, HDM_SETIMAGELIST, 0, (imageList.Handle).ToInt32());
        }

        public static void ClearColumnHeaderImage(ListView listView, int column) {
            LVCOLUMN col;
            col.mask = LVCF_FMT;
            col.fmt = 0;
            col.iImage = -1;
            col.cchTextMax = 0;
            col.cx = 0;
            col.iOrder = 0;
            col.iSubItem = 0;
            col.pszText = IntPtr.Zero;
            SendMessage(listView.Handle, (int)LVM_SETCOLUMN, column, ref col);
        }

        public static void SetColumnHeaderSorter(ListView listView, SubItemSorter sorter) {
            for (int i = 0; i < listView.Columns.Count; i++) {
                if (sorter == null || i != sorter.ColumnIndex)
                    ClearColumnHeaderImage(listView, i);
            }
            listView.ListViewItemSorter = sorter;
            if (sorter == null)
                return;
            SetColumnHeaderImage(listView, sorter.ColumnIndex,
                HorizontalImageAlignment.Right, (sorter.Asc ? WindowsArrow.WIN_ARROW_UP : WindowsArrow.WIN_ARROW_DOWN));
        }
    }
}
